package com.basic.inspection.service.impl;

import com.basic.common.exception.business.DataException;
import com.basic.inspection.dao.mapper.EquipmentLifeCycleExMapper;
import com.basic.inspection.dao.mapper.EquipmentLifeCycleMapper;
import com.basic.inspection.dao.model.EquipmentLifeCycle;
import com.basic.inspection.domain.EquipmentLifeCycleBo;
import com.basic.inspection.service.EquipmentLifeCycleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author wei
 * @Date 2024/9/13
 * @Description
 */

@Service
public class EquipmentLifeCycleServiceImpl implements EquipmentLifeCycleService {

    @Resource
    private EquipmentLifeCycleMapper equipmentLifeCycleMapper;

    @Resource
    private EquipmentLifeCycleExMapper equipmentLifeCycleExMapper;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 设备生命周期曲线数据
     * @param equipmentLifeCycleBo 实体类
     * @return List<EquipmentLifeCycle>
     */
    @Override
    public Map<String, List<EquipmentLifeCycle>> selLifeCycleData(EquipmentLifeCycleBo equipmentLifeCycleBo) {
        // 检查设备ID是否为空
        if (equipmentLifeCycleBo.getEquipmentIdList().isEmpty()) {
            logger.info("equipmentId为空  {}", equipmentLifeCycleBo.getEquipmentIdList());
            throw new DataException("设备ID不能为空");
        }
        // 查询设备生命周期数据
        List<EquipmentLifeCycle> equipmentLifeCycleList = equipmentLifeCycleExMapper.selLifeCycleData(equipmentLifeCycleBo);
        if (equipmentLifeCycleList.isEmpty()) {
            logger.info("设备ID不存在或下方无数据 {}", equipmentLifeCycleBo.getEquipmentId());
            return new HashMap<>();
        }
        Map<String, List<EquipmentLifeCycle>> mapList = equipmentLifeCycleList.stream().collect(Collectors.groupingBy(EquipmentLifeCycle::getEquipmentName));

        mapList.forEach((key,cycleList) -> {
            // 初始化一个列表来保存未来健康值
            List<EquipmentLifeCycle> futureHealthCycleList = new ArrayList<>();
            LocalDate currentDate = LocalDate.now();

            // 找到最新的healthValue
            BigDecimal latestHealthValue = null;
            //查询的数据是进行日期的升序排序 所以取size() - 1会拿到最新的生命值等数据 排序改变此处也做更改
            EquipmentLifeCycle cycleNow = cycleList.get(cycleList.size() - 1);
            latestHealthValue = cycleNow.getHealthValue();
            // 遍历equipmentLifeCycleList中的每一个EquipmentLifeCycle对象
            BigDecimal agingRate = cycleNow.getAgingRate() != null ? cycleNow.getAgingRate() : new BigDecimal("0.00009");

            // 计算未来15天的健康值
            for (int day = 0; day < 15; day++) {
                // 如果day等于0，则判断latestHealthValue是否为空，如果不为空，则将latestHealthValue减去agingRate赋值给dailyHealthValue，否则将cycleNew的healthValue减去agingRate赋值给dailyHealthValue
                // 否则，将futureHealthCycleList中最后一个元素的healthValue减去agingRate赋值给dailyHealthValue
                BigDecimal dailyHealthValue = (day == 0)
                        ? (latestHealthValue != null ? latestHealthValue.subtract(agingRate) : cycleNow.getHealthValue().subtract(agingRate))
                        : futureHealthCycleList.get(futureHealthCycleList.size() - 1).getHealthValue().subtract(agingRate);
                // 新建对象存储未来十五天的数据
                EquipmentLifeCycle futureCycle = new EquipmentLifeCycle();
                futureCycle.setEquipmentId(cycleNow.getEquipmentId());
                futureCycle.setHealthValue(dailyHealthValue);

                // 创建一个Date对象，表示当前日期加上指定天数后的日期
                Date logDate = Date.from(currentDate.plusDays(day).atStartOfDay(ZoneId.systemDefault()).toInstant());
                futureCycle.setLogdate(logDate);

                // 将futureCycle添加到futureHealthCycleList中
                futureHealthCycleList.add(futureCycle);
            }
            // 将futureHealthCycleList中的元素添加到equipmentLifeCycleList中
            cycleList.addAll(futureHealthCycleList);
        });

        return mapList;
    }
}
